﻿using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;

using Csla;
using Csla.Data;
using System.Data;
using System.Data.Common;

using Microsoft.Practices.EnterpriseLibrary.Data;
using buildingLib.security;

namespace buildingLib
{
    [Serializable()]
    public class Door:BusinessBase<Door>,IACL
    {
        #region ACL
        public Guid ACLID
        {
            get { return new Guid("{8FA41A98-3707-4a87-8280-A1DB72974CD0}"); }
        }
        public static Guid GetACLID()
        { return new Guid("{8FA41A98-3707-4a87-8280-A1DB72974CD0}"); }

        public string ACLName
        {
            get { return "房间信息"; }
        }

        public string ACLCategory
        {
            get { return "客服"; }
        }

        public string ACLDescription
        {
            get { return "房间信息管理(面积、朝向、户型)"; }
        }

        
        #endregion
        #region Business Method
        Guid m_id;
        string m_name = string.Empty;    
        Guid m_parentid;
        float m_area;
        string m_type = string.Empty;
        string m_memo = string.Empty;
        string m_orientation = string.Empty;
        double m_innerarea;
        double m_deckarea;
        double m_pubarea;
        double m_pubratio;
        
        public Guid ParentID
        {
            get { return m_parentid; }
        }
        public Guid ID
        {
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            get
            {
                CanReadProperty(true);
                return m_id;
            }
        }

        public string Name
        {
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            get
            {
                CanReadProperty(true);
                return m_name;
            }
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            set
            {
                CanWriteProperty(true);
                if (value == null) value = string.Empty;
                if (m_name != value)
                {
                    m_name = value;
                    PropertyHasChanged();
                }
            }
        }

        public string Orientation
        {
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            get
            {
                CanReadProperty(true);
                return m_orientation;
            }
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            set
            {
                CanWriteProperty(true);
                if (value == null) value = string.Empty;
                if (m_orientation != value)
                {
                    m_orientation = value;
                    PropertyHasChanged();
                }
            }
        }

        public string Type
        {
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            get
            {
                CanReadProperty(true);
                return m_type;
            }
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            set
            {
                CanWriteProperty(true);
                if (value == null) value = string.Empty;
                if (m_type != value)
                {
                    m_type = value;
                    PropertyHasChanged();
                }
            }
        }

        public float Area
        {
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            get
            {
                CanReadProperty(true);
                return m_area;
            }
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            set
            {
                CanWriteProperty(true);
                
                if (m_area != value)
                {
                    m_area = value;
                    PropertyHasChanged();
                }
            }
        }

        public double InnerArea
        {
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            get
            {
                CanReadProperty(true);
                return m_innerarea;
            }
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            set
            {
                CanWriteProperty(true);

                if (m_innerarea != value)
                {
                    m_innerarea = value;
                    PropertyHasChanged();
                }
            }
        }

        public double DeckArea
        {
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            get
            {
                CanReadProperty(true);
                return m_deckarea;
            }
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            set
            {
                CanWriteProperty(true);

                if (m_deckarea != value)
                {
                    m_deckarea = value;
                    PropertyHasChanged();
                }
            }
        }

        public double PubArea
        {
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            get
            {
                CanReadProperty(true);
                return m_pubarea;
            }
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            set
            {
                CanWriteProperty(true);

                if (m_pubarea != value)
                {
                    m_pubarea = value;
                    PropertyHasChanged();
                }
            }
        }

        public double PubRatio
        {
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            get
            {
                CanReadProperty(true);
                return m_pubratio;
            }
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            set
            {
                CanWriteProperty(true);

                if (m_pubratio != value)
                {
                    m_pubratio = value;
                    PropertyHasChanged();
                }
            }
        }

        public string Memo
        {
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            get
            {
                CanReadProperty(true);
                return m_memo;
            }
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            set
            {
                CanWriteProperty(true);
                if (value == null) value = string.Empty;
                if (m_memo != value)
                {
                    m_memo = value;
                    PropertyHasChanged();
                }
            }
        }
 
        protected override object GetIdValue()
        {
            return m_id;
        }
        #endregion

        
        #region Factory Method
        public static Door NewDoor(Guid parentid)
        {
            return DataPortal.Create<Door>(new Criteria(parentid));
        }

        public static Door GetDoor(Guid doorid)
        {
            return DataPortal.Fetch<Door>(new Criteria(doorid));
        }

        public static void DeleteDoor(Guid doorid)
        {
            DataPortal.Delete(new Criteria(doorid));
        }
        
        public Door()
        {
            
        }
        
        #endregion


        #region Validation
        protected override void AddBusinessRules()
        {
            ValidationRules.AddRule(
              Csla.Validation.CommonRules.StringRequired, "Name");
            ValidationRules.AddRule(
              Csla.Validation.CommonRules.StringMaxLength,
              new Csla.Validation.CommonRules.MaxLengthRuleArgs("Name", 50));
        }
        #endregion

        #region Authorization Rules

        protected override void AddAuthorizationRules()
        {
             
        }

        public static bool CanAddObject()
        {
            return Csla.ApplicationContext.User.IsInRole(
              "管理员") || Csla.ApplicationContext.User.IsInRole(
              "客服部");
        }

        public static bool CanGetObject()
        {
            return Csla.ApplicationContext.User.IsInRole("管理员") || Csla.ApplicationContext.User.IsInRole("客服部");
        }

        public static bool CanDeleteObject()
        {
            bool result = false;
            if (Csla.ApplicationContext.User.IsInRole(
              "管理员"))
                result = true;
            if (Csla.ApplicationContext.User.IsInRole(
              "客服部"))
                result = true;

            return result;
        }

        public static bool CanEditObject()
        {
            return Csla.ApplicationContext.User.IsInRole("管理员") || Csla.ApplicationContext.User.IsInRole("客服部");
        }

        #endregion

        #region DataAccess   
        private class Criteria
        {
            Guid _id;
            public Guid ID
            {
                get { return _id; }
            }
            public Criteria(Guid id)
            {
                _id = id;
            }
        }

        [RunLocal()]
        private  void DataPortal_Create(Criteria criteria)
        {
            m_id = Guid.NewGuid();
            m_parentid = criteria.ID;
            ValidationRules.CheckRules();
        }

        private void DataPortal_Fetch(Criteria criteria)
        {
            Database db = SQLDatabase.GetDatabase();
            DbCommand dbcom = db.GetStoredProcCommand("usp_GGetDoorByID");
            db.AddInParameter(dbcom, "id", DbType.Guid, criteria.ID);

            using (SafeDataReader dr = new SafeDataReader(db.ExecuteReader(dbcom)))
            {
                if (dr.Read())
                {
                    m_id = dr.GetGuid("id");
                    m_name = dr.GetString("name");
                    m_type = dr.GetString("type");
                    m_area = dr.GetFloat("area");
                    m_innerarea = dr.GetDouble("innerarea");
                    m_deckarea = dr.GetDouble("deckarea");
                    m_pubarea = dr.GetDouble("pubarea");
                    m_pubratio = dr.GetDouble("pubratio");
                    m_orientation = dr.GetString("orientation");
                    m_memo = dr.GetString("memo");
                }
            }              
        }

        [Transactional(TransactionalTypes.TransactionScope)]
        protected override void DataPortal_Insert()
        {
            Database db = SQLDatabase.GetDatabase();
            using (DbCommand dbcom = db.GetStoredProcCommand("usp_GInsertDoor"))
            {
                db.AddInParameter(dbcom, "parentid", DbType.Guid, m_parentid);
                DoInsertUpdate(dbcom);
                MarkOld();
            }
        }

        [Transactional(TransactionalTypes.TransactionScope)]
        protected override void DataPortal_Update()
        {            
            Database db = SQLDatabase.GetDatabase();
            using (DbCommand dbcom = db.GetStoredProcCommand("usp_GUpdateDoor"))
            {              
                DoInsertUpdate(dbcom);
                MarkOld();
            }
                  
        }

        private void DoInsertUpdate(DbCommand dbcom)
        {
            Database db = SQLDatabase.GetDatabase();
            db.AddInParameter(dbcom, "id", DbType.Guid, m_id);
            db.AddInParameter(dbcom, "name", DbType.String, m_name);                        
            db.AddInParameter(dbcom, "type", DbType.String, m_type);
            db.AddInParameter(dbcom, "area", DbType.Single, m_area);
            db.AddInParameter(dbcom, "memo", DbType.String, m_memo);
            db.AddInParameter(dbcom, "innerarea", DbType.Double, m_innerarea);
            db.AddInParameter(dbcom, "deckarea", DbType.Double, m_deckarea);
            db.AddInParameter(dbcom, "pubarea", DbType.Double, m_pubarea);
            db.AddInParameter(dbcom, "pubratio", DbType.Double, m_pubratio);
            db.AddInParameter(dbcom, "orientation", DbType.String, m_orientation);
                        
            db.ExecuteNonQuery(dbcom);            
        }


        [Transactional(TransactionalTypes.TransactionScope)]
        protected override void DataPortal_DeleteSelf()
        {
            DataPortal_Delete(new Criteria(m_id));
        }

        [Transactional(TransactionalTypes.TransactionScope)]
        private void DataPortal_Delete(Criteria criteria)
        {           
            Database db = SQLDatabase.GetDatabase();
            DbCommand dbcom = db.GetSqlStringCommand("update door set erased = 1 where id=@id");
            db.AddInParameter(dbcom, "id", DbType.Guid, criteria.ID);

            db.ExecuteNonQuery(dbcom);
            MarkNew();
        }        
        #endregion

    }
}
